﻿#include "plcworker.h"
#include <QDebug>
#include <QThread>

PlcWorker::PlcWorker(QObject *parent) : QObject(parent)
{
    m_bPlcConnect = false;
    m_serialPort = new QSerialPort();//实例化串口类一个对象
    if (m_serialPort->isOpen())//如果串口已经打开了 先给他关闭了
    {
        m_serialPort->clear();
        m_serialPort->close();
    }
    QStringList m_serialPortName;
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        m_serialPortName << info.portName();
    }

    if (m_serialPortName.size() > 0){
        //设置串口名字 假设我们上面已经成功获取到了 并且使用第一个
        m_serialPortName[0] = "COM1";
        m_serialPort->setPortName(m_serialPortName[0]);
        if (!m_serialPort->open(QIODevice::ReadWrite))//用ReadWrite 的模式尝试打开串口
        {
            qDebug() << m_serialPortName[0] << "打开失败!";
            return;
        }
        else{
            // 连接信号槽 当下位机发送数据QSerialPortInfo 会发送个 readyRead 信号, 我们定义个槽void receiveInfo()解析数据
            connect(m_serialPort, SIGNAL(readyRead()), this, SLOT(receiveInfo()));
            m_serialPort->setBaudRate(QSerialPort::Baud19200, QSerialPort::AllDirections);//设置波特率和读写方向
            m_serialPort->setDataBits(QSerialPort::Data8);		//数据位为8位
            m_serialPort->setFlowControl(QSerialPort::NoFlowControl);//无流控制
            m_serialPort->setParity(QSerialPort::EvenParity);	//无校验位
            m_serialPort->setStopBits(QSerialPort::OneStop); //一位停止位
            start();
        }
    }
    else {
        qDebug() << "serialPort erro!";
    }

}

PlcWorker::~PlcWorker()
{

}

void PlcWorker::Initialize()
{
    
}

void PlcWorker::start()
{
    // PLC 需要进行一次开始指令
    QByteArray sPlcHeart = "CR";
    sendInfo(sPlcHeart);
}


void PlcWorker::sendInfo(QByteArray sendBuf)
{
    QByteArray endBuf = "\r";
    sendBuf = sendBuf + endBuf;
    qDebug() << "sendInfo " << sendBuf;
    m_serialPort->write(sendBuf);////这句是真正的给单片机发数据 用到的是QIODevice::write 具体可以看文档
}

void PlcWorker::receiveInfo()
{
    QByteArray info = m_serialPort->readAll();
     qDebug() << "receiveInfo " << info;
    if( info == "CC\r\n"){
        m_bPlcConnect = true;
        return;
    }
    if( info == "E1\r\n"){
        m_bPlcConnect = false;
        return;
    }
    if( info == "OK\r\n"){
        return;
    }
    std::string str = info.toStdString();
    int pos = str.find("\r");
    str = str.substr(0,pos);
    int n = atoi(str.c_str());
    // 记录数据
    switch (m_nSig)
    {
    case START:
        m_coPlcInfo.Start = n;
        break;
    case STOP:
        m_coPlcInfo.Stop = n;
        break;
    case MOTOR1:
        m_coPlcInfo.Motor1  = n;
        break;
    case MOTOR2:
        m_coPlcInfo.Motor2  = n;
        break;
    case INCODERA:
        m_coPlcInfo.InCoderA  = n;
        break;
    case INCODERB:
        m_coPlcInfo.InCoderB  = n;
        break;
    case INSENSOR:
        m_coPlcInfo.InSensor  = n;
        break;
    case INPRESSSW1:
        m_coPlcInfo.InPressSw1  = n;
        break;
    case INPAUSESW:
        m_coPlcInfo.InPauseSw  = n;
        break;
    case INPRESSSW2:
        m_coPlcInfo.InPressSw2  = n;
        break;
    case ORIGINSW:
        m_coPlcInfo.originSw  = n;
        break;
    case QPULSE1:
        m_coPlcInfo.QPulse1  = n;
        break;
    case QPULSE2:
        m_coPlcInfo.QPulse2  = n;
        break;
    case QDIRECTION1:
        m_coPlcInfo.QDirection1  = n;
        break;
    case QDIRECTION2:
        m_coPlcInfo.QDirection2  = n;
        break;
    case QENABLED1:
        m_coPlcInfo.QEnabled1  = n;
        break;
    case QENABLED2:
        m_coPlcInfo.QEnabled2  = n;
        break;
    case QGRAP1:
        m_coPlcInfo.QGrap1  = n;
        break;
    case QGRAP2:
        m_coPlcInfo.QGrap2  = n;
        break;
    case QGRAP3:
        m_coPlcInfo.QGrap3  = n;
        break;
    case QGRAP4:
        m_coPlcInfo.QGrap4  = n;
        break;
    case QNG1OUTAIR:
        m_coPlcInfo.QNG1outAir   = n;
        break;
    case QNG2OUTAIR:
        m_coPlcInfo.QNG2outAir  = n;
        break;
    case QOKOUTAIR:
        m_coPlcInfo.QOKoutAir  = n;
        break;
    case QLINE:
        m_coPlcInfo.QLine = n;
        break;
    case QPLATE:
        m_coPlcInfo.QPlate  = n;
        break;
    case QINAIR:
        m_coPlcInfo.QinAir  = n;
        break;
    case QVACUOINOUT:
        m_coPlcInfo.QVacuoInOut  = n;
        break;
    case QLIGHTG:
        m_coPlcInfo.QLightG  = n;
        break;
    case QLIGHTY:
        m_coPlcInfo.QLightY  = n;
        break;
    case QLIGHTR:
        m_coPlcInfo.QLightR  = n;
        break;
    case QLIGHTVOX:
        m_coPlcInfo.QLightVox  = n;
        break;
    case PLATEREV:
        m_coPlcInfo.PlateRev  = n;
        break;
    case MOTORRATION1:
        m_coPlcInfo.MotorRation1  = n;
        break;
    case MOTORRATION2:
        m_coPlcInfo.MotorRation2  = n;
        break;
    case OPTICAL:
        m_coPlcInfo.Optical  = n;
        break;
    case POSITION_1:
        m_coPlcInfo.Position_1  = n;
        break;
    case POSITION_2:
        m_coPlcInfo.Position_2  = n;
        break;
    case POSITION_3:
        m_coPlcInfo.Position_3  = n;
        break;
    case POSITION_4:
        m_coPlcInfo.Position_4  = n;
        break;
    case POSITION_NG1:
        m_coPlcInfo.Position_NG1  = n;
        break;
    case POSITION_NG2:
        m_coPlcInfo.Position_NG2  = n;
        break;
    case POSITION_OK:
        m_coPlcInfo.Position_OK  = n;
        break;
    case RESULT_NUMBER:
        m_coPlcInfo.Result_number  = n;
        break;
    case CAMERA_RESULT:
        m_coPlcInfo.Camera_result  = n;
        break;
    case WARN:
        m_coPlcInfo.Warn = n;
        break;
    case ERROR_TIME:
        m_coPlcInfo.Error_time = n;
        break;
    case ERROR_SITE:
        m_coPlcInfo.Error_site = n;
        break;
    case STOP_TIME:
        m_coPlcInfo.Stop_time = n;
        break;
    default:
        break;
    }
}

void PlcWorker::readPlcInfo(SIG_PLC nSig)
{
    m_nSig = nSig;
    if(!m_bPlcConnect){
        return;
    }
    QByteArray start = "RD ";
    QByteArray sendBuf;
    switch (nSig)
    {
    case START:
    case STOP:
        sendBuf = "MR0";
        break;
    case INCODERA:
        sendBuf = "R4";
        break;
    case INCODERB:
        sendBuf = "R5";
        break;
    case INSENSOR:
        sendBuf = "R6";
        break;
    case INPRESSSW1:
        sendBuf = "R7";
        break;
    case INPAUSESW:
        sendBuf = "R8";
        break;
    case INPRESSSW2:
        sendBuf = "R9";
        break;
    case ORIGINSW:
        sendBuf = "R10";
        break;
    case QPULSE1:
        sendBuf = "R500";
        break;
    case QPULSE2:
        sendBuf = "R501";
        break;
    case QDIRECTION1:
        sendBuf = "R502";
        break;
    case QDIRECTION2:
        sendBuf = "R503";
        break;
    case QENABLED1:
        sendBuf = "R504";
        break;
    case QENABLED2:
        sendBuf = "R505";
        break;
    case QGRAP1:
        sendBuf = "R506";
        break;
    case QGRAP2:
        sendBuf = "R507";
        break;
    case QGRAP3:
        sendBuf = "R508";
        break;
    case QGRAP4:
        sendBuf = "R509";
        break;
    case QNG1OUTAIR:
        sendBuf = "R1500";
        break;
    case QNG2OUTAIR:
        sendBuf = "R1501";
        break;
    case QOKOUTAIR:
        sendBuf = "R1502";
        break;
    case QLINE:
        sendBuf = "R1503";
        break;
    case QPLATE:
        sendBuf = "R1504";
        break;
    case QINAIR:
        sendBuf = "R1505";
        break;
    case QVACUOINOUT:
        sendBuf = "R1506";
        break;
    case QLIGHTG:
        sendBuf = "R1507";
        break;
    case QLIGHTY:
        sendBuf = "R1508";
        break;
    case QLIGHTR:
        sendBuf = "R1509";
        break;
    case QLIGHTVOX:
        sendBuf = "R1510";
        break;
    case OPTICAL:
        sendBuf = "DM0";
        break;
    case PLATEREV:
        sendBuf = "DM100";
        break;
    case MOTORRATION1:
        sendBuf = "DM102";
        break;
    case MOTORRATION2:
        sendBuf = "DM104";
        break;
    case POSITION_1:
        sendBuf = "DM110";
        break;
    case POSITION_2:
        sendBuf = "DM112";
        break;
    case POSITION_3:
        sendBuf = "DM114";
        break;
    case POSITION_4:
        sendBuf = "DM116";
        break;
    case POSITION_NG1:
        sendBuf = "DM118";
        break;
    case POSITION_NG2:
        sendBuf = "DM120";
        break;
    case POSITION_OK:
        sendBuf = "DM122";
        break;
    case RESULT_NUMBER:
        sendBuf = "DM124";
        break;
    case CAMERA_RESULT:
        sendBuf = "DM126";
        break;
    case WARN:
        sendBuf = "DM106";
        break;
    case ERROR_TIME:
        sendBuf = "DM28";
        break;
    case ERROR_SITE:
        sendBuf = "DM108";
        break;
    case STOP_TIME:
        sendBuf = "DM150";
        break;
    default:
        break;
    }
    sendBuf = start + sendBuf;
    sendInfo(sendBuf);
}

void PlcWorker::writePlcInfo(SIG_PLC nSig, int nIndex)
{
    m_nSig = 0;
    if(!m_bPlcConnect){
        return;
    }
    QByteArray start = "WR ";
    QByteArray sK = " ";
    QByteArray index = QString::number(nIndex).toUtf8();
    QByteArray sendBuf;
    switch (nSig)
    {
    case START:
        sendBuf = "MR100";
        break;
    case STOP:
        sendBuf = "MR101";
        break;
    case MOTOR1:
        sendBuf = "MR102";
        break;
    case MOTOR2:
        sendBuf = "MR103";
        break;
    case QPULSE1:
        sendBuf = "MR300";
        break;
    case QPULSE2:
        sendBuf = "MR301";
        break;
    case QDIRECTION1:
        sendBuf = "MR302";
        break;
    case QDIRECTION2:
        sendBuf = "MR303";
        break;
    case QENABLED1:
        sendBuf = "MR304";
        break;
    case QENABLED2:
        sendBuf = "MR305";
        break;
    case QGRAP1:
        sendBuf = "MR306";
        break;
    case QGRAP2:
        sendBuf = "MR307";
        break;
    case QGRAP3:
        sendBuf = "MR308";
        break;
    case QGRAP4:
        sendBuf = "MR309";
        break;
    case QNG1OUTAIR:
        sendBuf = "MR310";
        break;
    case QNG2OUTAIR:
        sendBuf = "MR311";
        break;
    case QOKOUTAIR:
        sendBuf = "MR312";
        break;
    case QLINE:
        sendBuf = "MR313";
        break;
    case QPLATE:
        sendBuf = "MR314";
        break;
    case QINAIR:
        sendBuf = "MR315";
        break;
    case QVACUOINOUT:
        sendBuf = "MR400";
        break;
    case QLIGHTG:
        sendBuf = "MR401";
        break;
    case QLIGHTY:
        sendBuf = "MR402";
        break;
    case QLIGHTR:
        sendBuf = "MR403";
        break;
    case QLIGHTVOX:
        sendBuf = "MR404";
        break;
    case PLATEREV:
        sendBuf = "DM100";
        break;
    case MOTORRATION1:
        sendBuf = "DM102";
        break;
    case MOTORRATION2:
        sendBuf = "DM104";
        break;
    case OPTICAL:
        sendBuf = "DM0";
        break;
    case POSITION_1:
        sendBuf = "DM110";
        break;
    case POSITION_2:
        sendBuf = "DM112";
        break;
    case POSITION_3:
        sendBuf = "DM114";
        break;
    case POSITION_4:
        sendBuf = "DM116";
        break;
    case POSITION_NG1:
        sendBuf = "DM118";
        break;
    case POSITION_NG2:
        sendBuf = "DM120";
        break;
    case POSITION_OK:
        sendBuf = "DM122";
        break;
    case RESULT_NUMBER:
        sendBuf = "DM124";
        break;
    case CAMERA_RESULT:
        sendBuf = "DM126";
        break;
    case WARN:
        sendBuf = "DM106";
        break;
    case ERROR_TIME:
        sendBuf = "DM28";
        break;
    case ERROR_SITE:
        sendBuf = "DM108";
        break;
    case STOP_TIME:
        sendBuf = "DM150";
        break;
    default:
        break;
    }
    sendBuf = start + sendBuf + sK + index;
    sendInfo(sendBuf);
}


void PlcWorker::writePlcInfo(SIG_PLC nSig, float nIndex)
{
    int nIndex1=0;
    int nIndex2=0;
    splitFloat(nIndex,nIndex1,nIndex2);

    QByteArray start = "WR ";
    QByteArray sK = " ";

    QByteArray index1 = QString::number(nIndex1).toUtf8();
    QByteArray index2 = QString::number(nIndex2).toUtf8();
    QByteArray sendBuf1;
    QByteArray sendBuf2;
    switch (nSig)
    {
    case PLATEREV:
        sendBuf1 = "DM202";
        sendBuf2 = "DM204";
        break;
    case MOTORRATION1:
        sendBuf1 = "DM212";
        sendBuf2 = "DM214";
        break;
    case MOTORRATION2:
        sendBuf1 = "DM222";
        sendBuf2 = "DM224";
        break;

    default:
        break;
    }
    sendBuf1 = start + sendBuf1 + sK + index1;
    sendBuf2 = start + sendBuf2 + sK + index2;
    sendInfo(sendBuf1);
    sendInfo(sendBuf2);
}

void PlcWorker::splitFloat(float fIndex,int& nIndex1,int& nIndex2){
    float fData;
    fData = fIndex;
    nIndex1 = (int)fIndex;
    nIndex2 = (int)((fData - nIndex1)*10);
}
